﻿using System;
using System.IO;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Data;
using System.Windows.Forms;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Threading;

using MediaLibrary.Controls;

using AMPLibrary;
using AMPLibrary.Collections;
using AMPLibrary.Controllers;
using AMPLibrary.Media;
using AMPLibrary.Windows;

namespace MediaLibrary
{
    /// <summary>
    /// Interaction logic for NowPlayingPage.xaml
    /// </summary>
    public partial class NowPlayingPage : System.Windows.Controls.Page
    {   
        //
        private static NowPlayingPage nowPlayingPage;

        //
        private AMPLibrary.Media.MediaPlayer mediaPlayer;

        //
        private NowPlayingCollection nowPlayingCollection = NowPlayingCollection.GetNowPlayingCollection();

        // holds the value of the current full screen status
        private bool fullScreenStatus;

        //
        private double mediaCanvasWidth;

        //
        private double onScreenControlsWidth;

        // 
        private double previousVolumn;

        //
        private double previousPlaylistColumnSize;
        
        //
        private GlobalKeyboardHook globalKeyboardHook;

        //
        private bool IsDragging { get; set; }

        //
        private MediaFile DraggedMedia;

        //
        private int errorCount;

        //
        private DispatcherTimer fullScreenMouseTimeoutDispatcherTimer;

        //
        private bool isTimelineDragging;
          
        /// <summary>
        /// 
        /// </summary>
        private NowPlayingPage()
        {
            InitializeComponent();

            // set the error count
            errorCount = 0;
            
            // setup the various key entries
            this.SizeChanged += new SizeChangedEventHandler(nowPlayingPage_SizeChanged);
            this.KeyDown += new System.Windows.Input.KeyEventHandler(nowPlayingPage_KeyDown);
            this.mediaContentPresenter.KeyDown += new System.Windows.Input.KeyEventHandler(nowPlayingPage_KeyDown);
            this.LayoutRoot.KeyDown += new System.Windows.Input.KeyEventHandler(nowPlayingPage_KeyDown);
            this.mainGrid.KeyDown += new System.Windows.Input.KeyEventHandler(nowPlayingPage_KeyDown);

            // volume
            this.previousVolumn = Settings.Volume;

            // setup the AMP with reference to the video canvas
            this.mediaPlayer = AMPLibrary.Media.MediaPlayer.GetMediaPlayer(ref this.mediaContentPresenter, ref this.mediaInformationContentPresenter);
            this.mediaPlayer.OnMediaEnded += new MediaEndedEventHandler(mediaPlayer_MediaEnded);
            this.mediaPlayer.OnMediaFailed += new MediaFailedEventHandler(mediaPlayer_MediaFailed);

            this.nowPlayingListView.ItemTemplateSelector = new NowPlayingDataTemplateSelector();
            this.nowPlayingListView.ItemsSource = mediaPlayer.NowPlayingCollection;
            this.nowPlayingCollection.ItemAdded += new ChangedEventHandler(nowPlayingCollection_Changed);
            this.nowPlayingCollection.ItemsAdded += new ChangedEventHandler(nowPlayingCollection_Changed);
            this.nowPlayingCollection.ItemRemoved += new ChangedEventHandler(nowPlayingCollection_Changed);
            this.nowPlayingCollection.ItemsRemoved += new ChangedEventHandler(nowPlayingCollection_Changed);
            this.nowPlayingCollection.ItemsChanged += new ChangedEventHandler(nowPlayingCollection_Changed);
            
            // get the attributes of the previous instance of this application size
            this.mediaPlayerColumn.Width = new GridLength(Settings.NowPlayingWidth);
            this.previousPlaylistColumnSize = this.playlistColumn.Width.Value;
            
            // timeline setup
            this.isTimelineDragging = false;

            // volume display
            this.volumnSlider.Value = previousVolumn;

            // repeat and random
            this.randomCheckBox.IsChecked = Settings.Random;
            this.repeatCheckBox.IsChecked = Settings.Repeat;

            // always on top = false
            Settings.AlwaysOnTop = false;

            // display settings
            this.fullScreenStatus = false;

            this.globalKeyboardHook = GlobalKeyboardHook.GetGlobalKeyboardHook();
            this.globalKeyboardHook.HookedKeys.Add(Keys.MediaNextTrack);
            this.globalKeyboardHook.HookedKeys.Add(Keys.MediaPlayPause);
            this.globalKeyboardHook.HookedKeys.Add(Keys.MediaPreviousTrack);
            this.globalKeyboardHook.HookedKeys.Add(Keys.MediaStop);
            this.globalKeyboardHook.HookedKeys.Add(Keys.Escape);
            this.globalKeyboardHook.KeyDown += new System.Windows.Forms.KeyEventHandler(globalKeyboardHook_KeyDown);
            this.globalKeyboardHook.Hook();

            // set the inital focus to the playlist
            this.nowPlayingListView.Focus();

            // setup property watchers
            this.mediaPlayer.PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler(mediaPlayer_PropertyChanged);
            this.totalTimeTextBlock.Text = "00:00:00";
            this.currentPlayTime.Text = "00:00:00";
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void mediaPlayer_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
        {
            if (e.PropertyName == "TotalPlayTimeTimeSpan")
            {
                mediaTimeLineSlider.Maximum = mediaPlayer.TotalPlayTimeTimeSpan.TotalMilliseconds;
                totalTimeTextBlock.Text = " " + String.Format("{0:00}:{1:00}:{2:00}", mediaPlayer.TotalPlayTimeTimeSpan.Hours, mediaPlayer.TotalPlayTimeTimeSpan.Minutes, mediaPlayer.TotalPlayTimeTimeSpan.Seconds);
            }
            
            if (e.PropertyName == "CurrentPlayTimeTimeSpan")
            {
                currentPlayTime.Text = " " + String.Format("{0:00}:{1:00}:{2:00}", mediaPlayer.CurrentPlayTimeTimeSpan.Hours, mediaPlayer.CurrentPlayTimeTimeSpan.Minutes, mediaPlayer.CurrentPlayTimeTimeSpan.Seconds);
                
                if(isTimelineDragging == false)
                    mediaTimeLineSlider.Value = mediaPlayer.CurrentPlayTimeTimeSpan.TotalMilliseconds;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public static NowPlayingPage GetNowPlayingPage()
        {
            if (nowPlayingPage == null)
                nowPlayingPage = new NowPlayingPage();

            return nowPlayingPage;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void globalKeyboardHook_KeyDown(object sender, System.Windows.Forms.KeyEventArgs e)
        {
            if (e.KeyCode == Keys.MediaPlayPause)
                this.playButton_OnClick(sender, EventArgs.Empty);

            if (e.KeyCode == Keys.MediaStop)
                this.stopButton_OnClick(sender, EventArgs.Empty);

            if (e.KeyCode == Keys.MediaPreviousTrack)
                this.previousButton_OnClick(sender, EventArgs.Empty);

            if (e.KeyCode == Keys.MediaNextTrack)
                this.nextButton_OnClick(sender, EventArgs.Empty);

            if (e.KeyCode == Keys.Escape)
            {
                if (fullScreenStatus == false)
                    return;

                fullScreenStatus = false;
                ChangeFullScreenStatus(fullScreenStatus);
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void nowPlayingCollection_Changed(object sender, EventArgs e)
        {
            this.nowPlayingListView.ItemsSource = this.mediaPlayer.NowPlayingCollection;
            this.nowPlayingListView.Items.Refresh();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="source"></param>
        /// <param name="e"></param>
        private void mediaPlayer_MediaFailed(object source, EventArgs e)
        {
            // add to the error counter
            errorCount++;

            // exit at so many errors
            if (errorCount >= 10)
            {
                stopButton_OnClick(source, e);
                return;
            }

            if (this.mediaPlayer.Next())
            {
                this.playButton.Content = "Pause";

                if (MediaTypes.IsValidVideoMediaType(this.mediaPlayer.CurrentMedia.Path))
                    this.mediaPlayerGrid.Background = Brushes.Black;
                else
                    this.mediaPlayerGrid.Background = Brushes.Transparent;
            }

            nowPlayingListView.Items.Refresh();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="source"></param>
        /// <param name="e"></param>
        private void mediaPlayer_MediaEnded(object source, EventArgs e)
        {
            // reset the error counter
            errorCount = 0;

            if (this.mediaPlayer.Next())
            {
                this.playButton.Content = "Pause";

                if (MediaTypes.IsValidVideoMediaType(this.mediaPlayer.CurrentMedia.Path))
                    this.mediaPlayerGrid.Background = Brushes.Black;
                else
                    this.mediaPlayerGrid.Background = Brushes.Transparent;
            }

            nowPlayingListView.Items.Refresh();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void nowPlayingPage_SizeChanged(object sender, SizeChangedEventArgs e)
        {
            if (e.PreviousSize.Width == 0)
                return;

            double size = e.PreviousSize.Width - e.NewSize.Width;

            if (this.mediaPlayerColumn.Width.Value - size <= 0)
                return;

            this.mediaPlayerColumn.Width = new GridLength(this.mediaPlayerColumn.Width.Value - size);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void nowPlayingPage_KeyDown(object sender, System.Windows.Input.KeyEventArgs e)
        {
        }

        /// <summary>
        /// Method, changes the full screen status of the player
        /// </summary>
        /// <param name="fullScreen"></param>
        public void ChangeFullScreenStatus(bool fullScreen)
        {
            if (fullScreen)
            {
                MainWindow window = (MainWindow)App.Current.Windows[0];
                if (window != null)
                    window.ShowMainMenuControls(false);

                if (window.pagePlaceHolder != null)
                    window.ToggleMargin(false);
                
                //// make the function buttons invisible 
                this.mainGrid.RowDefinitions[1].Height = new GridLength(0);

                // save the width of the non full sized canvas
                this.mediaCanvasWidth = this.mainGrid.ColumnDefinitions[0].ActualWidth;
                double windowWidth = FullScreenHelper.GoFullscreen(App.Current.Windows[0]);

                //// change the size of the now playing and playlist columns
                this.mainGrid.ColumnDefinitions[1].Width = new GridLength(0);
                this.mainGrid.ColumnDefinitions[0].Width = new GridLength(windowWidth);

                if (this.mediaPlayer.CurrentMedia != null)
                {
                    // make sure the background is black
                    if (MediaTypes.IsValidVideoMediaType(this.mediaPlayer.CurrentMedia.Path))
                        this.mediaPlayerGrid.Background = Brushes.Black;
                    else
                        this.mediaPlayerGrid.Background = Brushes.Transparent;
                }
                else
                    this.mediaPlayerGrid.Background = Brushes.Transparent;

                // change the toggle full screen text
                this.fullScreenMenuItem.Header = "Remove Full Screen";
                this.fullScreenMenuItem1.Header = "Remove Full Screen";

                // make sure the playlist grid and splitter are invisible
                this.playlistGrid.Visibility = Visibility.Hidden;
                this.playlistGridSplitter.Visibility = Visibility.Hidden;
            }
            else
            {
                MainWindow window = (MainWindow)App.Current.Windows[0];
                if (window != null)
                    window.ShowMainMenuControls(true);

                if (window.pagePlaceHolder != null)
                    window.ToggleMargin(true);

                App.Current.Windows[0].WindowState = WindowState.Normal;
                App.Current.Windows[0].WindowStyle = WindowStyle.SingleBorderWindow;
                App.Current.Windows[0].Topmost = false;
                App.Current.Windows[0].ShowInTaskbar = true;
                App.Current.Windows[0].ResizeMode = ResizeMode.CanMinimize | ResizeMode.CanResize;
                
                // make the function buttons visible
                this.mainGrid.RowDefinitions[1].Height = new GridLength(35);

                // change the size of the now playing and playlist columns
                this.mainGrid.ColumnDefinitions[0].Width = new GridLength(this.mediaCanvasWidth);
                this.mainGrid.ColumnDefinitions[1].Width = new GridLength(1, GridUnitType.Star);

                // change the toggle full screen text
                this.fullScreenMenuItem.Header = "Full Screen";
                this.fullScreenMenuItem1.Header = "Full Screen";

                if (this.mediaPlayer.CurrentMedia != null)
                {
                    // make sure the background is black
                    if (MediaTypes.IsValidVideoMediaType(this.mediaPlayer.CurrentMedia.Path))
                        this.mediaPlayerGrid.Background = Brushes.Black;
                    else
                        this.mediaPlayerGrid.Background = Brushes.Transparent;
                }
                else
                    this.mediaPlayerGrid.Background = Brushes.Transparent;

                // make sure the playlist grid and splitter are visible
                this.playlistGrid.Visibility = Visibility.Visible;
                this.playlistGridSplitter.Visibility = Visibility.Visible;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void showOnScreenControlsMenuItem_Click(object sender, RoutedEventArgs e)
        {
            if (this.mainGrid.RowDefinitions[1].Height.Value == 35.0f)
            {
                MainWindow window = (MainWindow)App.Current.Windows[0];
                if (window != null)
                    window.ShowMainMenuControls(false);

                if (window.pagePlaceHolder != null)
                    window.ToggleMargin(false);

                this.mainGrid.RowDefinitions[1].Height = new GridLength(0);

                if (!fullScreenStatus)
                {
                    window.WindowStyle = WindowStyle.None;
                    window.ResizeMode = ResizeMode.CanMinimize | ResizeMode.NoResize;

                    this.onScreenControlsWidth = this.mainGrid.ColumnDefinitions[0].ActualWidth;

                    this.mainGrid.ColumnDefinitions[1].Width = new GridLength(0);
                    this.mainGrid.ColumnDefinitions[0].Width = new GridLength(1, GridUnitType.Star); 

                    if (this.mediaPlayer.CurrentMedia != null)
                    {
                        if (MediaTypes.IsValidVideoMediaType(this.mediaPlayer.CurrentMedia.Path))
                            this.mediaPlayerGrid.Background = Brushes.Black;
                        else
                            this.mediaPlayerGrid.Background = Brushes.Transparent;
                    }
                    else
                        this.mediaPlayerGrid.Background = Brushes.Transparent;
                }

                showOnScreenControlsMenuItem.Header = "Show On Screen Controls";
                showOnScreenControlsMenuItem1.Header = "Show On Screen Controls";

                this.playlistGrid.Visibility = Visibility.Hidden;
                this.playlistGridSplitter.Visibility = Visibility.Hidden;
            }
            else
            {
                this.mainGrid.RowDefinitions[1].Height = new GridLength(35);

                MainWindow window = (MainWindow)App.Current.Windows[0];
                if (window != null)
                    window.ShowMainMenuControls(true);

                if (window.pagePlaceHolder != null)
                    window.ToggleMargin(true);

                if (!fullScreenStatus)
                {
                    window.ToggleMargin(true);
                    window.WindowState = WindowState.Normal;
                    window.WindowStyle = WindowStyle.SingleBorderWindow;
                    window.Topmost = false;
                    window.ShowInTaskbar = true;
                    window.ResizeMode = ResizeMode.CanMinimize | ResizeMode.CanResize;

                    this.playlistGrid.Visibility = Visibility.Visible;
                    this.playlistGridSplitter.Visibility = Visibility.Visible;

                    this.mainGrid.ColumnDefinitions[0].Width = new GridLength(this.onScreenControlsWidth);
                    this.mainGrid.ColumnDefinitions[1].Width = new GridLength(1, GridUnitType.Star);
                }

                showOnScreenControlsMenuItem.Header = "Remove On Screen Controls";
                showOnScreenControlsMenuItem1.Header = "Remove On Screen Controls";
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void alwaysOnTopMenuItem_Click(object sender, RoutedEventArgs e)
        {
            Settings.AlwaysOnTop = !Settings.AlwaysOnTop;

            MainWindow window = (MainWindow)App.Current.Windows[0];
            if (window != null)
            {
                if (Settings.AlwaysOnTop)
                {
                    alwaysOnTopeMenuItem.Header = "Remove Always On Top";
                    alwaysOnTopeMenuItem1.Header = "Remove Always On Top";
                }
                else
                {
                    alwaysOnTopeMenuItem.Header = "Always On Top";
                    alwaysOnTopeMenuItem1.Header = "Always On Top";
                }

                window.Topmost = Settings.AlwaysOnTop;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void fullScreenMenuItem_Click(object sender, RoutedEventArgs e)
        {
            this.fullScreenStatus = !this.fullScreenStatus;
            ChangeFullScreenStatus(this.fullScreenStatus);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void mediaPlayerGrid_SizeChanged(object sender, EventArgs e)
        {
            double width = ((GridLength)this.mediaPlayerColumn.Width).Value;

            if (fullScreenStatus)
            {
                width = App.Current.Windows[0].Width;
                Settings.NowPlayingWidth = width;
                return;
            }
            
            if (width >= (this.mediaPlayerColumn.ActualWidth + this.playlistColumn.ActualWidth))
            {
                this.mediaPlayerColumn.Width = new GridLength(this.mainGrid.ActualWidth - 175);
                width = this.mediaPlayerColumn.Width.Value;
            }

            if (width >= (this.mediaPlayerColumn.ActualWidth + this.playlistColumn.ActualWidth - 175))
            {
                this.mediaPlayerColumn.Width = new GridLength(this.mainGrid.ActualWidth - 175);
                width = this.mediaPlayerColumn.Width.Value;
            }

            Settings.NowPlayingWidth = width;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void randomCheckBox_OnClick(object sender, EventArgs e)
        {
            System.Windows.Controls.CheckBox randomCheckBox = (System.Windows.Controls.CheckBox)sender;
            if (randomCheckBox == null)
                return;

            mediaPlayer.Random = randomCheckBox.IsChecked.Value;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void repeatCheckBox_OnClick(object sender, EventArgs e)
        {
            System.Windows.Controls.CheckBox repeatCheckBox = (System.Windows.Controls.CheckBox)sender;
            if (repeatCheckBox == null)
                return;

            mediaPlayer.Repeat = repeatCheckBox.IsChecked.Value;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void stopButton_OnClick(object sender, EventArgs e)
        {
            if (this.fullScreenStatus == true)
                this.ChangeFullScreenStatus(false);

            this.mediaPlayer.Stop();

            this.playButton.IsChecked = false;

            this.mediaPlayerGrid.Background = Brushes.Transparent;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void previousButton_OnClick(object sender, EventArgs e)
        {
            if (this.mediaPlayer.Previous())
            {
                this.playButton.Content = "Pause";

                if (MediaTypes.IsValidVideoMediaType(this.mediaPlayer.CurrentMedia.Path))
                    this.mediaPlayerGrid.Background = Brushes.Black;
                else
                    this.mediaPlayerGrid.Background = Brushes.Transparent;
            }

            nowPlayingListView.Items.Refresh();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void playButton_OnClick(object sender, EventArgs e)
        {
            if (mediaPlayer.CurrentMediaPlayerState == MediaPlayerState.Playing)
            {
                mediaPlayer.Pause();
                this.playButton.IsChecked = false;
            }
            else if (mediaPlayer.CurrentMediaPlayerState == MediaPlayerState.Paused)
            {
                mediaPlayer.Pause();
                this.playButton.IsChecked = true;
            }
            else
            {
                nextButton_OnClick(sender, e);
                nowPlayingListView.Items.Refresh();
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void nextButton_OnClick(object sender, EventArgs e)
        {
            if (this.mediaPlayer.Next())
            {
                this.playButton.IsChecked = true;

                if (MediaTypes.IsValidVideoMediaType(this.mediaPlayer.CurrentMedia.Path))
                    this.mediaPlayerGrid.Background = Brushes.Black;
                else
                    this.mediaPlayerGrid.Background = Brushes.Transparent;
            }

            nowPlayingListView.Items.Refresh();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void volumnSlider_OnValueChanged(object sender, EventArgs e)
        {
            RoutedPropertyChangedEventArgs<double> volumn = e as RoutedPropertyChangedEventArgs<double>;
            mediaPlayer.SetVolumn(volumn.NewValue);
            Settings.Volume = volumn.NewValue;

            if (volumn.NewValue != 0.0)
                this.muteButton.IsChecked = false;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void muteButton_OnClick(object sender, EventArgs e)
        {
            ToggleButton tb = (ToggleButton)sender;
            if (tb == null)
                return;

            if (Convert.ToBoolean(tb.IsChecked))
            {
                previousVolumn = volumnSlider.Value;
                volumnSlider.Value = 0.0;
            }
            else
            {
                volumnSlider.Value = previousVolumn;
                previousVolumn = volumnSlider.Value;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void nowPlayingListView_OnKeyDown(object sender, System.Windows.Input.KeyEventArgs e)
        {
            if (e.Key == Key.G)
            {
                GoToWindow goToWindow = new GoToWindow();
                goToWindow.SetKeyboardFocus();

                if (goToWindow.ShowDialog().Value == true)
                    nowPlayingListView.Items.Refresh();
            }

            if (e.Key == Key.Enter)
            {
                MediaFile media = (MediaFile)nowPlayingListView.SelectedItem;
                if (media == null)
                    return;

                mediaPlayer.CurrentlySelectedIndex = nowPlayingListView.SelectedIndex;

                if (this.mediaPlayer.Play(ref media))
                {
                    this.playButton.Content = "Pause";

                    if (MediaTypes.IsValidVideoMediaType(media.Path))
                        this.mediaPlayerGrid.Background = Brushes.Black;
                    else
                        this.mediaPlayerGrid.Background = Brushes.Transparent;
                }

                this.nowPlayingListView.Items.Refresh();
            }

            if (e.Key == Key.Delete)
            {
                Collection<MediaFile> mediaToRemove = new Collection<MediaFile>();

                if (this.nowPlayingListView.SelectedItems.Count == 0)
                    return;

                foreach (MediaFile media in this.nowPlayingListView.SelectedItems)
                    mediaToRemove.AddItem(media);

                foreach (MediaFile media in mediaToRemove)
                    nowPlayingCollection.RemoveItem(media);

                this.nowPlayingListView.Items.Refresh();
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void nowPlayingListView_OnMouseDoubleClick(object sender, MouseButtonEventArgs e)
        {
            MediaFile media = (MediaFile)nowPlayingListView.SelectedItem;
            if (media == null)
                return;

            mediaPlayer.CurrentlySelectedIndex = nowPlayingListView.SelectedIndex;

            if (this.mediaPlayer.Play(ref media))
            {
                this.playButton.Content = "Pause";

                if (MediaTypes.IsValidVideoMediaType(media.Path))
                    this.mediaPlayerGrid.Background = Brushes.Black;
                else
                    this.mediaPlayerGrid.Background = Brushes.Transparent;
            }

            this.nowPlayingListView.Items.Refresh();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void nowPlayingListView_OnMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            IsDragging = true;

            var listViewItem = VisualElementsHelper.TryFindFromPoint<System.Windows.Controls.ListViewItem>((UIElement)sender, e.GetPosition(nowPlayingListView));
            if (listViewItem == null)
                return;

            //set flag that indicates we're capturing mouse movements
            IsDragging = true;
            DraggedMedia = (MediaFile)listViewItem.Content;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void OnMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            if (!IsDragging)
                return;

            if (nowPlayingListView.SelectedItems.Count > 1)
                return;

            //get the target item
            MediaFile targetItem = (MediaFile)nowPlayingListView.SelectedItem;

            if (targetItem == null || !ReferenceEquals(DraggedMedia, targetItem))
            {
                //get target index
                var targetIndex = nowPlayingCollection.IndexOf(targetItem);

                //remove the source from the list
                nowPlayingCollection.RemoveItem(DraggedMedia);

                //move source at the target's location
                nowPlayingCollection.InsertItem(targetIndex, DraggedMedia);

                //select the dropped item
                nowPlayingListView.SelectedItem = DraggedMedia;
            }

            IsDragging = false;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void fullScreenMouseTimeoutTimer_Tick(object sender, EventArgs e)
        {
            if (fullScreenStatus == false)
                return;

            Mouse.OverrideCursor = System.Windows.Input.Cursors.None;
            fullScreenMouseTimeoutDispatcherTimer.Stop();
            fullScreenMouseTimeoutDispatcherTimer.IsEnabled = false;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void OnMouseMove(object sender, System.Windows.Input.MouseEventArgs e)
        {
            Mouse.OverrideCursor = null;

            if (fullScreenStatus == true)
            {
                if (fullScreenMouseTimeoutDispatcherTimer == null)
                {
                    this.fullScreenMouseTimeoutDispatcherTimer = new DispatcherTimer();
                    this.fullScreenMouseTimeoutDispatcherTimer.Tick += new EventHandler(fullScreenMouseTimeoutTimer_Tick);
                    this.fullScreenMouseTimeoutDispatcherTimer.Interval = new TimeSpan(0, 0, 0, 10, 0);
                }

                this.fullScreenMouseTimeoutDispatcherTimer.IsEnabled = true;
                this.fullScreenMouseTimeoutDispatcherTimer.Start();

                return;
            }

            if (!IsDragging || e.LeftButton != MouseButtonState.Pressed)
                return;

            //make sure the row under the grid is being selected
            Point position = e.GetPosition(nowPlayingListView);

            var uiElement = VisualElementsHelper.TryFindFromPoint<System.Windows.Controls.ListViewItem>(nowPlayingListView, position);

            if (uiElement != null)
                nowPlayingListView.SelectedItem = uiElement;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void nowPlayingListView_OnDrop(object sender, System.Windows.DragEventArgs e)
        {
            if (e.Data.GetDataPresent(System.Windows.DataFormats.FileDrop))
            {
                string[] files = (string[])e.Data.GetData("FileDrop");

                foreach (string file in files)
                {
                    string[] parts = file.Split('\\');

                    if (Directory.Exists(file))
                        LoadDirectory(file);
                    else
                    {
                        MediaFile media = MediaFile.LoadMedia(file);
                        this.nowPlayingCollection.AddItem(media);
                    }
                }
            }

            this.nowPlayingListView.Items.Refresh();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void savePlaylistMenuItem_OnClick(object sender, EventArgs e)
        {
            NowPlayingCollection npc = NowPlayingCollection.GetNowPlayingCollection();

            NewPlaylistWindow npw = new NewPlaylistWindow(npc);

            if (npw.ShowDialog().Value == true)
            {
                PlaylistCollection playlistCollection = PlaylistCollection.GetPlaylistCollection();
                playlistCollection.AddItem(new Playlist() { Path = npw.PlaylistPath, Title = System.IO.Path.GetFileName(npw.PlaylistPath) });
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void loadPlaylistMenuItem_OnClick(object sender, EventArgs e)
        {
            OpenFileDialog openFileDialog = new OpenFileDialog();
            openFileDialog.Filter = "M3U Playlist (*.m3u)|*.m3u | Windows Play List (*.wpl)|*.wpl|All files (*.*)|*.*";

            if (openFileDialog.ShowDialog() == DialogResult.OK)
            {
                Playlist playlist = new Playlist();
                Collection<MediaFile> mediaCollection = Playlist.LoadPlaylist(openFileDialog.FileName);

                this.nowPlayingCollection.ClearItems();

                foreach (MediaFile item in mediaCollection)
                    this.nowPlayingCollection.AddItem(item);

                this.nowPlayingListView.ItemsSource = this.nowPlayingCollection;
                this.nowPlayingListView.Items.Refresh();
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void loadPlaylistFromCollectionMenuItem_OnClick(object sender, EventArgs e)
        {
            PlaylistSelectionWindow psw = new PlaylistSelectionWindow();

            if (psw.ShowDialog().Value == true)
            {
                Playlist playlist = psw.SelectedPlaylist;
                Collection<MediaFile> mediaCollection = Playlist.LoadPlaylist(playlist.Path);

                this.nowPlayingCollection.ClearItems();

                foreach (MediaFile item in mediaCollection)
                    this.nowPlayingCollection.AddItem(item);
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void addFileMenuItem_OnClick(object sender, EventArgs e)
        {
            OpenFileDialog openFileDialog = new OpenFileDialog();
            openFileDialog.Multiselect = true;
            openFileDialog.Filter = MediaTypes.MediaTypeFilter;

            if (openFileDialog.ShowDialog() == DialogResult.OK)
            {
                foreach (string filename in openFileDialog.FileNames)
                {
                    string[] parts = filename.Split('\\');

                    MediaFile media = MediaFile.LoadMedia(filename);
                    this.nowPlayingCollection.AddItem(media);
                }

                this.nowPlayingListView.Items.Refresh();
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void addPlaylistMenuItem_OnClick(object sender, EventArgs e)
        {
            OpenFileDialog openFileDialog = new OpenFileDialog();
            openFileDialog.Multiselect = true;
            openFileDialog.Filter = "M3U Playlist(s)|*.m3u|All files (*.*)|*.*";

            if (openFileDialog.ShowDialog() == DialogResult.OK)
            {
                Playlist playlist = new Playlist();
                foreach (string filename in openFileDialog.FileNames)
                {
                    Collection<MediaFile> mediaCollection = Playlist.LoadPlaylist(filename);

                    foreach (MediaFile item in mediaCollection)
                        this.nowPlayingCollection.AddItem(item);
                }

                this.nowPlayingListView.Items.Refresh();
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void removeAllMenuItem_OnClick(object sender, EventArgs e)
        {
            Mouse.OverrideCursor = System.Windows.Input.Cursors.Wait;

            this.nowPlayingCollection.ClearItems();
            this.nowPlayingListView.Items.Refresh();

            Mouse.OverrideCursor = null;

        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void removeSelectedMenuItem_OnClick(object sender, EventArgs e)
        {
            Mouse.OverrideCursor = System.Windows.Input.Cursors.Wait;

            Collection<MediaFile> mediaToRemove = new Collection<MediaFile>();

            foreach (MediaFile media in this.nowPlayingListView.SelectedItems)
                mediaToRemove.AddItem(media);

            foreach (MediaFile media in mediaToRemove)
                nowPlayingCollection.RemoveItem(media);

            this.nowPlayingListView.Items.Refresh();
            
            Mouse.OverrideCursor = null;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void cropMenuItem_OnClick(object sender, EventArgs e)
        {
            IEnumerator enum1 = this.nowPlayingCollection.GetEnumerator();
            Collection<MediaFile> mediaToRemove = new Collection<MediaFile>();

            while (enum1.MoveNext())
            {
                MediaFile media = (MediaFile)enum1.Current;

                if (!this.nowPlayingListView.SelectedItems.Contains(media))
                    mediaToRemove.AddItem(media);
            }

            foreach (MediaFile media in mediaToRemove)
                nowPlayingCollection.RemoveItem(media);

            this.nowPlayingListView.Items.Refresh();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void selectAllMenuItem_OnClick(object sender, EventArgs e)
        {
            this.nowPlayingListView.SelectAll();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void invertSelectionMenuItem_OnClick(object sender, EventArgs e)
        {
            Mouse.OverrideCursor = System.Windows.Input.Cursors.Wait;

            IEnumerator enum1 = this.nowPlayingCollection.GetEnumerator();
            ArrayList mediaToSelect = new ArrayList();

            while (enum1.MoveNext())
            {
                MediaFile media = (MediaFile)enum1.Current;

                if (!this.nowPlayingListView.SelectedItems.Contains(media))
                    mediaToSelect.Add(media);
            }

            this.nowPlayingListView.SelectedItems.Clear();

            foreach (MediaFile media in mediaToSelect)
                this.nowPlayingListView.SelectedItems.Add(media);

            this.nowPlayingListView.Items.Refresh();

            Mouse.OverrideCursor = null;

        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void clearSelectionMenuItem_OnClick(object sender, EventArgs e)
        {
            this.nowPlayingListView.SelectedItems.Clear();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void randomizeMenuItem_OnClick(object sender, EventArgs e)
        {
            this.nowPlayingCollection.RandomizeItems();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void reverseListMenuItem_OnClick(object sender, EventArgs e)
        {
            this.nowPlayingCollection.ReverseItems();
            this.nowPlayingListView.Items.Refresh();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void sortByTitleMenuItem_OnClick(object sender, EventArgs e)
        {
            this.nowPlayingCollection.Sort(new SortMediaByTitle());
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void sortByPathMenuItem_OnClick(object sender, EventArgs e)
        {
            this.nowPlayingCollection.Sort(new SortMediaByPath());
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void gotoMenuItem_OnClick(object sender, EventArgs e)
        {
            GoToWindow goToWindow = new GoToWindow();
            goToWindow.SetKeyboardFocus();

            if (goToWindow.ShowDialog().Value == true)
                this.nowPlayingListView.Items.Refresh();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void playItemMenuItem_OnClick(object sender, EventArgs e)
        {
            MediaFile media = (MediaFile)nowPlayingListView.SelectedItem;
            if (media == null)
                return;

            mediaPlayer.CurrentlySelectedIndex = nowPlayingListView.SelectedIndex;

            if (this.mediaPlayer.Play(ref media))
            {
                this.playButton.Content = "Pause";

                if (MediaTypes.IsValidVideoMediaType(media.Path))
                    this.mediaPlayerGrid.Background = Brushes.Black;
                else
                    this.mediaPlayerGrid.Background = Brushes.Transparent;
            }

            this.nowPlayingListView.Items.Refresh();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="directoryName"></param>
        private void LoadDirectory(string directoryName)
        {
            DirectoryInfo directory = new DirectoryInfo(directoryName);

            foreach (DirectoryInfo subDirectory in directory.GetDirectories())
                LoadDirectory(subDirectory.FullName);

            foreach (FileInfo file in directory.GetFiles())
            {
                try
                {
                    MediaFile media = MediaFile.LoadMedia(file.FullName);
                    this.nowPlayingCollection.AddItem(media);
                }
                catch
                {
                }
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void mediaCanvas_MouseDown(object sender, MouseButtonEventArgs e)
        {
            if (e.ClickCount == 2)
            {
                this.fullScreenStatus = !this.fullScreenStatus;
                ChangeFullScreenStatus(this.fullScreenStatus);
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void mediaTimeLineSlider_DragCompleted(object sender, DragCompletedEventArgs e)
        {
            isTimelineDragging = false;
            mediaPlayer.GotoTime(((Slider)sender).Value);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void mediaTimeLineSlider_DragStarted(object sender, DragStartedEventArgs e)
        {
            isTimelineDragging = true;
        }
    }
}